//
//  NSString+ZRExtension.m
//  简书:https://www.jianshu.com/u/043e94ca450f
//
//  Created by 黄涛 on 2018/8/3.
//  Copyright © 2018年 zero. All rights reserved.
//

#import "NSString+ZRExtension.h"
#import <CommonCrypto/CommonCrypto.h>
@implementation NSString (ZRExtension)


#pragma mark - -----------------------  格式化 ----------------------
/** 去除首尾空格 */
- (NSString *)zr_delSpace{
    
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

/** 去除所有空格 注意:此时生成的str是autorelease属性的，不要妄想对strUrl进行release操作。 */
- (NSString *)zr_delAllSpace{
    
   return [self stringByReplacingOccurrencesOfString:@" " withString:@""];
}



#pragma mark - ----------------------- 正则方法 ----------------------
/** 判断 手机号 */
- (BOOL)zr_isPhoneNum{
    
    //手机号以13， 15，18开头，八个 \d 数字字符
    NSString *phoneRegex = @"^1[3|4|5|7|8][0-9]\\d{8}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    return [phoneTest evaluateWithObject:self];
}

/** 判断身份证号 */
- (BOOL)zr_isIdCard{
    
    NSString *pattern = @"(^[0-9]{15}$)|([0-9]{17}([0-9]|X)$)";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    return [pred evaluateWithObject:self];
}

/** 判断 邮箱 */
- (BOOL)zr_isEmail{
    
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}

/** 判断 车牌号*/
- (BOOL)zr_isCarNo{
    
    NSString *carRegex = @"^[\u4e00-\u9fa5]{1}[a-zA-Z]{1}[a-zA-Z_0-9]{4}[a-zA-Z_0-9_\u4e00-\u9fa5]$";
    NSPredicate *carTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",carRegex];
    
    return [carTest evaluateWithObject:self];
}

/** 判断 url */
- (BOOL)zr_isUrl{
    
    NSString *pattern = @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    return [pred evaluateWithObject:self];
}

/** 判断 纯数字 */
- (BOOL)zr_isNumber{

    NSString *numberRegex = @"[0-9]*";
    NSPredicate *numberTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",numberRegex];
    return [numberTest evaluateWithObject:self];
}

/** 判断 纯字母 */
- (BOOL)zr_isEnglish{
    
    NSString *englishRegex = @"[a-zA-Z]*";
    NSPredicate *englishTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",englishRegex];
    return [englishTest  evaluateWithObject:self];
}

/** 判断 纯汉字 */
- (BOOL)zr_isChinese{
    
    NSString *chineseRegex = @"[\u4e00-\u9fa5]+";
    NSPredicate *chineseTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",chineseRegex];
    return [chineseTest evaluateWithObject:self];
}



/** 检查 用户名(1 - 15 位) */
- (BOOL)zr_checkAccount{
    
    NSString * regex = @"^[A-Za-z0-9]{1,15}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:self];
}

/** 检查 密码(min - max 位) 数字.字母.下划线 组合 */
- (BOOL)zr_checkPasswordMin:(int)a max:(int)b{
    
    NSString *pattern = [NSString stringWithFormat:@"^([a-zA-Z]|[a-zA-Z0-9_]|[0-9]){%d,%d}$",a,b];
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
   return [pred evaluateWithObject:self];
    
}


/** 检查 银行卡号 */
- (BOOL)zr_checkBankCard{
    NSString * lastNum = [[self substringFromIndex:(self.length-1)] copy];//取出最后一位
    NSString * forwardNum = [[self substringToIndex:(self.length -1)] copy];//前15或18位
    
    NSMutableArray * forwardArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i=0; i<forwardNum.length; i++) {
        NSString * subStr = [forwardNum substringWithRange:NSMakeRange(i, 1)];
        [forwardArr addObject:subStr];
    }
    
    NSMutableArray * forwardDescArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i = (int)(forwardArr.count-1); i> -1; i--) {//前15位或者前18位倒序存进数组
        [forwardDescArr addObject:forwardArr[i]];
    }
    
    NSMutableArray * arrOddNum = [[NSMutableArray alloc] initWithCapacity:0];//奇数位*2的积 < 9
    NSMutableArray * arrOddNum2 = [[NSMutableArray alloc] initWithCapacity:0];//奇数位*2的积 > 9
    NSMutableArray * arrEvenNum = [[NSMutableArray alloc] initWithCapacity:0];//偶数位数组
    
    for (int i=0; i< forwardDescArr.count; i++) {
        NSInteger num = [forwardDescArr[i] intValue];
        if (i%2) {//偶数位
            [arrEvenNum addObject:[NSNumber numberWithInteger:num]];
        }else{//奇数位
            if (num * 2 < 9) {
                [arrOddNum addObject:[NSNumber numberWithInteger:num * 2]];
            }else{
                NSInteger decadeNum = (num * 2) / 10;
                NSInteger unitNum = (num * 2) % 10;
                [arrOddNum2 addObject:[NSNumber numberWithInteger:unitNum]];
                [arrOddNum2 addObject:[NSNumber numberWithInteger:decadeNum]];
            }
        }
    }
    
    __block  NSInteger sumOddNumTotal = 0;
    [arrOddNum enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumOddNumTotal += [obj integerValue];
    }];
    
    __block NSInteger sumOddNum2Total = 0;
    [arrOddNum2 enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumOddNum2Total += [obj integerValue];
    }];
    
    __block NSInteger sumEvenNumTotal =0 ;
    [arrEvenNum enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumEvenNumTotal += [obj integerValue];
    }];
    
    NSInteger lastNumber = [lastNum integerValue];
    
    NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
    
    return (luhmTotal%10 ==0)?YES:NO;
}


#pragma mark - ----------------------- 计算尺寸 ----------------------
/** 计算文字 宽度 font:字号 maxH:最大高度 */
- (CGFloat)zr_calculateWidthWithFont:(CGFloat)font maxHeight:(CGFloat)maxH{
    
    CGRect rect = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, maxH) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}
                                     context:nil];
    return rect.size.width;

}

/** 计算文字 宽度 font:字号 maxW:最大宽度 */
- (CGFloat)zr_calculateHeightWithFont:(CGFloat)font maxWidth:(CGFloat)maxW{
    
    CGRect rect = [self boundingRectWithSize:CGSizeMake(maxW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]} context:nil];
    
    return rect.size.height;
}

#pragma mark - ----------------------- 散列函数 ----------------------
/** MD5 加密 */
- (NSString *)zr_md5String {
    
    const char *str = self.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), buffer);

    NSMutableString *strM = [NSMutableString string];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [strM appendFormat:@"%02x", buffer[i]];
    }
    return [strM copy];
}

/** SHA1 加密 :可修改参数更换 加密 如:SHA512 */
- (NSString *)zr_sha1String {
    const char *str = self.UTF8String;
    // 修改参数，变换散列计算SHA1、SHA256、SHA512
    // uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    // CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(str, (CC_LONG)strlen(str), buffer);
    
    NSMutableString *strM = [NSMutableString string];
    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
        [strM appendFormat:@"%02x", buffer[i]];
    }
    return [strM copy];
    
}


@end
